package io.kwdb.sdk;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * Main interface for KWDB client operations. Provides methods for writing data points and querying
 * the database. This interface is thread-safe when implemented properly.
 */
public interface KwdbClient extends AutoCloseable {

  /**
   * Write a single point to KWDB.
   *
   * @param point The data point to write
   * @return Status indicating success or failure
   */
  Status write(Point point);

  /**
   * Write a batch of points to KWDB.
   *
   * @param batch The list of data points to write
   * @return Status indicating success or failure
   */
  Status batchWrite(List<Point> batch);

  /**
   * Write a single point to KWDB asynchronously.
   *
   * @param point The data point to write
   * @return CompletableFuture with Status indicating success or failure
   */
  CompletableFuture<Status> writeAsync(Point point);

  /**
   * Execute a SQL query against KWDB.
   *
   * @param sql The SQL query string
   * @return QueryResult containing the result set or error information
   */
  QueryResult query(String sql);

  /**
   * Flush any pending writes to the server. This method ensures all buffered data is sent. In M1,
   * this can be a no-op, but the interface is kept for future use.
   */
  void flush();

  /**
   * Close the client and release all resources. After calling this method, the client cannot be
   * used anymore.
   *
   * @throws Exception if an error occurs during closing
   */
  @Override
  void close() throws Exception;

  /**
   * Check if the client is closed.
   *
   * @return true if the client is closed, false otherwise
   */
  boolean isClosed();

  /**
   * Static factory method to create a new client instance. Selects implementation based on
   * config.getTransport().
   *
   * @param config The configuration for the client
   * @return A new KwdbClient instance
   */
  static KwdbClient create(Config config) {
    switch (config.getTransport()) {
      case ILP:
        return new IlpClient(config);
      case GRPC:
      default:
        return new GrpcKwdbClient(config);
    }
  }
}
